/**
 * @file nac_helper.h
 * NDN gateway's common header
 * Chengyu Fan <chengyu@cs.colostate.edu>
 */

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#include <ccn/ccn.h>
#include <ccn/uri.h>
#include <ccn/face_mgmt.h>
#include <ccn/reg_mgmt.h>
#include <ccn/charbuf.h>

#define MAXBUFLEN 250
#define MAXPORTLEN 50
#define MAXNAMELEN 255

#define MSGACT 0
#define ACTACK 1
#define ACTNACK 2

#define TCP 6
#define UDP 17
////////////////
#define CCN_DEFAULT_UNICAST_PORT       "9695"
#define OP_REG  0
#define OP_UNREG 1

struct global_data{
    struct ccn_charbuf *local_scope_template;
    size_t ccndid_size;
    struct ccn_charbuf *no_name;
    const unsigned char *ccndid;
};

///////////////////////////////////////////////////
typedef char * string;

struct prefixes{
    char name[255];
    struct prefixes *next;
};

struct ccn_dhcp_entry {
    struct ccn_charbuf *name_prefix;
    const char address[20];
    const char port[10];
    struct ccn_charbuf *store;
    struct ccn_dhcp_entry *next;
};

struct pheader{//packet header
    uint8_t ver;
    uint8_t msgType;
    uint16_t length;
}__attribute__((__packed__));

struct packet_act{//active msg
    uint32_t addr;
    uint16_t port;
    uint8_t prot;//protocol, 6 for TCP and 17 for UDP
    uint8_t nameLen;
}__attribute__((__packed__));

struct packet_ack{//active ACK msg
    uint32_t addr;
    uint16_t port;
    uint8_t prot;//protocol, 6 for TCP and 17 for UDP
    uint8_t end;//just for make this packet a word boundary
}__attribute__((__packed__));

/*
 * private types
 */
struct prefix_face_list_item {
    struct ccn_charbuf *prefix;
    struct ccn_face_instance *fi;
    int flags;
    struct prefix_face_list_item *next;
};


extern string Concat (string s1, string s2);

struct pheader *get_header(uint8_t type);

struct packet_act *get_packet_act(char *myip, int iport, int len, int protocol);

struct packet_ack *get_packet_ack(char *myip, int port, int protocol);

int is_valid_act(struct pheader *header);

int is_valid_response(struct pheader *header);

///////////////////////
void initialize_global_data(struct ccn_charbuf *local_scope_template, struct ccn_charbuf *no_name);

int process_command_tokens(struct prefix_face_list_item *pfltail, int lineno, char *cmd, char *uri, char *proto, char *host, char *port, char *flags, char *mcastttl, char *mcastifi, char *fibttl);

int get_ccndid(struct ccn *h, const unsigned char *ccndid, size_t ccndid_storage_size, struct ccn_charbuf *local_scope_template);

void process_prefix_face_list_item(struct ccn *h, struct prefix_face_list_item *pfl, struct global_data *g_data);

void prefix_face_list_destroy(struct prefix_face_list_item **pflpp);



